﻿namespace YunQue.Services.System
{
    /// <summary>
    /// 用户服务接口
    /// </summary>
    public class UserService : YunQueBaseService, IScoped
    {
        private readonly PermissionService _permissionService;
        private readonly TimeSpan USEREXPIRY = TimeSpan.FromDays(30);
        /// <summary>
        /// 构造函数
        /// </summary>
        /// <param name="serviceProvider"></param>
        /// <param name="permissionService"></param>
        public UserService(IServiceProvider serviceProvider, PermissionService permissionService) : base(serviceProvider)
        {
            _permissionService = permissionService;
        }
        /// <summary>
        /// 新增用户
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task<string> AddUserAsync(UserInfo user)
        {
            if (user == null) return string.Empty;
            var orgPassword = RandomStrHelper.GeneratePassword(8);
            var userEntity = new UserEntity()
            {
                Name = user.Name,
                Password = AesEncryption.Encrypt(orgPassword),
            };
            using (_dbContext)
            {
                await _dbContext.Users.AddAsync(userEntity).ConfigureAwait(false);
                await _dbContext.SaveChangesAsync().ConfigureAwait(false);
                var cacheUser = BuildUserInfo(userEntity);
                RedisWrapper.Set(AppSettingManager.CACHEKEY_USER + cacheUser.Id, cacheUser, USEREXPIRY);
                return orgPassword;
            }
        }
        /// <summary>
        /// 删除用户
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<bool> DeleteUserByIdAsync(string id)
        {
            bool isDeleted = false;
            using (var transaction = _dbContext.Database.BeginTransaction())
            {
                var user = await _dbContext.Users.FirstOrDefaultAsync(x => x.Id == id).ConfigureAwait(false);
                if (user == null) return false;
                _dbContext.Users.Remove(user);
                await RedisWrapper.RemoveAsync(AppSettingManager.CACHEKEY_USER + id).ConfigureAwait(false);
                await _dbContext.SaveChangesAsync().ConfigureAwait(false);
                transaction.Commit();
                isDeleted = true;
            }
            if(isDeleted)
            {
                await _permissionService.RemoveUserPermissionsAsync(id).ConfigureAwait(false);
            }
            return isDeleted;
        }
        /// <summary>
        /// 更新用户信息
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        public async Task<bool> UpdateUserInfoAsync(UserInfo user)
        {
            if(user == null || string.IsNullOrWhiteSpace(user.Id)) return false;
            var updateUser = await _dbContext.Users.FirstOrDefaultAsync(x => x.Id == user.Id);
            if (updateUser == null) return false;
            updateUser.Name = user.Name;
            updateUser.Avatar = user.Avatar;
            _dbContext.Users.UpdateRange(updateUser);
            //更新缓存
            var cacheUser = BuildUserInfo(updateUser);
            RedisWrapper.Set(AppSettingManager.CACHEKEY_USER + cacheUser.Id, cacheUser, USEREXPIRY);
            return await _dbContext.SaveChangesAsync().ConfigureAwait(false) > 0;
        }
        /// <summary>
        /// 修改密码
        /// </summary>
        /// <param name="password"></param>
        /// <returns></returns>
        public async Task<bool> UpdatePasswordAsync(string password)
        {
            if (string.IsNullOrWhiteSpace(password)) return false;
            password = RASEncryption.Decrypt(password);
            var mySelf = await _dbContext.Users.FirstOrDefaultAsync(x => x.Id == _userContext.Id);
            if (mySelf == null) return false;
            mySelf.Password = AesEncryption.Encrypt(password);
            _dbContext.Users.UpdateRange(mySelf);
            return await _dbContext.SaveChangesAsync().ConfigureAwait(false) > 0;
        }
        /// <summary>
        /// 获取用户列表
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        public async Task<ApiPageResultModel<UserInfo>> GetListAsync(ApiPageRequestModel<UserListRequest> request)
        {
            var parameter = request?.Parameter;
            ApiPageResultModel<UserInfo> objRet = new ApiPageResultModel<UserInfo>();
            if (request == null || parameter == null || request.PageIndex <= 0 || request.PageSize <= 0) return objRet;
            int total = 0;
            List<UserEntity> datas = null;
            var query = _dbContext.Users.AsQueryable().WhereIf(!string.IsNullOrWhiteSpace(parameter.UserName), p => p.Name.IndexOf(parameter.UserName) > -1);
            (total, datas) = await query.QueryDataByPageAsync(request.PageIndex, request.PageSize).ConfigureAwait(false);
            objRet.Total = total;
            objRet.Datas = datas.Select(x =>
            {
                return BuildUserInfo(x);
            }).ToList();
            return objRet;
        }

        /// <summary>
        /// 获取用户信息
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public async Task<UserInfo> GetUserByIdAsync(string id)
        {
            if(string.IsNullOrWhiteSpace(id)) return null;
            var cacheKey = AppSettingManager.CACHEKEY_USER + id;
            var userInfo = await RedisWrapper.GetAsync<UserInfo>(cacheKey).ConfigureAwait(false);
            string tenantCode = string.Empty;
            if (userInfo != null)
            {
                tenantCode = userInfo.TenantCode;
            }
            else
            {
                var user = await _dbContext.Users.FirstOrDefaultAsync(x => x.Id == id).ConfigureAwait(false);
                if (user == null) throw new Exception("用户不存在");
                userInfo = BuildUserInfo(user);
                //缓存用户信息
                RedisWrapper.Set(cacheKey, userInfo, USEREXPIRY);
            }
            return userInfo;
        }

        /// <summary>
        /// 根据用户名和密码获取用户信息
        /// </summary>
        /// <param name="userName"></param>
        /// <param name="password"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        public async Task<UserInfo> GetUserByPassword(string userName,string password)
        {
            string userId = await _dbContext.Users.Where(x => x.Name == userName && x.Password == password).Select(p => p.Id).FirstOrDefaultAsync().ConfigureAwait(false);
            if (string.IsNullOrWhiteSpace(userId)) throw new Exception("用户不存在");
            return await GetUserByIdAsync(userId).ConfigureAwait(false);
        }
        /// <summary>
        /// 构建用户信息
        /// </summary>
        /// <param name="user"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        private UserInfo BuildUserInfo(UserEntity user)
        {
            if (user == null) throw new Exception("用户不存在");
            return new UserInfo()
            {
                Id = user.Id,
                Name = user.Name,
                Avatar = user.Avatar,
                TenantCode = user.TenantCode,
            };
        }
    }
}
